package org.mijia.dotsbox.rcp;

import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.part.ViewPart;
import org.mijia.dotsbox.DotsboxApp;
import org.mijia.dotsbox.DotsboxAppGui;
import org.mijia.dotsbox.core.ChannelDao;
import org.mijia.dotsbox.core.FolderDao;
import org.mijia.dotsbox.core.model.Channel;
import org.mijia.dotsbox.core.model.Folder;
import org.mijia.dotsbox.task.ChannelUpdateTask;
import org.mijia.dotsbox.task.Task;
import org.mijia.dotsbox.task.TaskEventListener;

public class DotsboxChannelView extends ViewPart implements TaskEventListener {
	public static final String ID = "org.mijia.dotsbox.channelview";
	
	private TreeViewer viewer;
	private ChannelTreeModel treeModel;
	
	@Override
	public void createPartControl(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        layout.horizontalSpacing = 0;
        layout.verticalSpacing = 0;
        composite.setLayout(layout);
        initToolbar(composite);
        
        treeModel = new ChannelTreeModel();
        viewer = new TreeViewer(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
        viewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
        viewer.setContentProvider(new TreeContentProvider());
        viewer.setLabelProvider(new TreeLabelProvider());
        viewer.setInput(treeModel.getRoot());
        
        DotsboxApp.getInstance().getTaskDispatcher().addEventListener(this);
	}

	// for the ugly tool bar
	private void initToolbar(Composite composite) {
		ViewForm boxForm = new ViewForm(composite, SWT.FLAT | SWT.BORDER);
        boxForm.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true,
                        false));
        boxForm.setOnlyBorderTopBottom(true);
        boxForm.setBackground(boxForm.grayViewFormColor);
        
        GridLayout boxFormLayout = new GridLayout(1, false);
        boxFormLayout.marginWidth = 3;
        boxFormLayout.marginHeight = 1;
        boxFormLayout.marginTop = 1;

        Composite boxFormHeader = new Composite(boxForm, SWT.NONE);
        boxFormHeader.setLayout(boxFormLayout);
        boxFormHeader.setBackground(boxForm.grayViewFormColor);
        boxFormHeader.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true,
                false));
        boxForm.setContent(boxFormHeader, true);

        ToolBar actionBar = new ToolBar(boxFormHeader, SWT.FLAT | SWT.NO_FOCUS);
        actionBar.setBackground(boxForm.grayViewFormColor);
        actionBar.setLayoutData(new GridData(SWT.BEGINNING, SWT.END, false, false));
        
        ToolItem newFolderAction = new ToolItem(actionBar, SWT.PUSH);
        newFolderAction.setImage(DotsboxAppGui.getImage("icons/views/folder_add.png"));
        newFolderAction.setToolTipText("New channle folder");
        newFolderAction.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				onNewFolder();
			}
        });
        
        ToolItem newChannelAction = new ToolItem(actionBar, SWT.PUSH);
        newChannelAction.setImage(DotsboxAppGui.getImage("icons/views/feed_add.png"));
        newChannelAction.setToolTipText("New RSS channel");
        newChannelAction.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				onNewChannel();
			}
        });
        
        ToolItem reloadAction = new ToolItem(actionBar, SWT.PUSH);
        reloadAction.setImage(DotsboxAppGui.getImage("icons/views/reload.gif"));
        reloadAction.setToolTipText("Reload all news channel");
        
        ToolItem refreshAction = new ToolItem(actionBar, SWT.PUSH);
        refreshAction.setImage(DotsboxAppGui.getImage("icons/views/refresh.gif"));
        refreshAction.setToolTipText("Reload news channel");
        
        ToolItem sepTool = new ToolItem(actionBar, SWT.SEPARATOR | SWT.VERTICAL);
        
        ToolItem importAction = new ToolItem(actionBar, SWT.PUSH);
        importAction.setImage(DotsboxAppGui.getImage("icons/views/import.gif"));
        importAction.setToolTipText("Import");
        
        ToolItem exportAction = new ToolItem(actionBar, SWT.PUSH);
        exportAction.setImage(DotsboxAppGui.getImage("icons/views/export.gif"));
        exportAction.setToolTipText("Export");
        
        sepTool = new ToolItem(actionBar, SWT.SEPARATOR | SWT.VERTICAL);
        
        ToolItem markReadAction = new ToolItem(actionBar, SWT.PUSH);
        markReadAction.setImage(DotsboxAppGui.getImage("icons/views/markread.png"));
        markReadAction.setToolTipText("Mark As Read");
	}
	
	private void onNewFolder() {
		NewFolderDialog dialog = new NewFolderDialog(DotsboxAppGui.getInstance().getShell(), treeModel);
		if (dialog.open() == Window.OK) {
			String folderName = dialog.getFolderName();
			Folder folder = new Folder();
			folder.setName(folderName);
			folder.setParentId(DotsboxApp.getInstance().getRootFolder().getId());
			FolderDao fdao = (FolderDao) DotsboxApp.getInstance().getProfile().getDao(Folder.class);
			fdao.save(folder);
			
			treeModel.addChild(treeModel.getRoot(), folder);
			viewer.refresh(treeModel.getRoot(), true);
			viewer.expandToLevel(treeModel.getRoot(), 1);
		}
	}
	
	private void onNewChannel() {
		Folder folder = null;
		ChannelTreeModel.TreeNode parentNode = null;
		IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
		if (selection != null && !selection.isEmpty()) {
			parentNode = (ChannelTreeModel.TreeNode) selection.getFirstElement();
			if (parentNode.getEntity() instanceof Folder) {
				folder = (Folder) parentNode.getEntity();
			}
		}
		
		NewChannelDialog dialog = new NewChannelDialog(folder, DotsboxAppGui.getInstance().getShell(), treeModel);
		if (dialog.open() == Window.OK) {
			String link = dialog.getInputUrl();
			String pid = folder == null ? DotsboxApp.getInstance().getRootFolder().getId() : folder.getId();
			
			Channel channel = new Channel();
			channel.setTitle(link);
			channel.setParentId(pid);
			ChannelDao cdao = (ChannelDao) DotsboxApp.getInstance().getProfile().getDao(Channel.class);
			cdao.save(channel);
			
			DotsboxApp.getInstance().getTaskDispatcher().execute(new ChannelUpdateTask(channel));
			
			if (parentNode != null) {
				treeModel.addChild(parentNode, channel);
				viewer.refresh(parentNode, true);
				viewer.expandToLevel(parentNode, 1);
			} else {
				treeModel.addChild(treeModel.getRoot(), channel);
				viewer.refresh(treeModel.getRoot(), true);
				viewer.expandToLevel(treeModel.getRoot(), 1);				
			}
		}
	}

	
	/* (non-Javadoc)
	 * @see org.mijia.dotsbox.task.TaskEventListener#taskEndExecute(org.mijia.dotsbox.task.Task)
	 */
	public void taskEndExecute(Task task) {
		// TODO:
	}

	/* (non-Javadoc)
	 * @see org.mijia.dotsbox.task.TaskEventListener#taskStartExecute(org.mijia.dotsbox.task.Task)
	 */
	public void taskStartExecute(Task task) {
		// TODO:
	}

	@Override
	public void setFocus() {
		viewer.getControl().setFocus();
	}

	class TreeContentProvider implements ITreeContentProvider {

		public Object[] getChildren(Object parentElement) {
			ChannelTreeModel.TreeNode node = (ChannelTreeModel.TreeNode) parentElement;
			return treeModel.getChildren(node);
		}

		public Object getParent(Object element) {
			ChannelTreeModel.TreeNode node = (ChannelTreeModel.TreeNode) element;
			return node.getParent();
		}

		public boolean hasChildren(Object element) {
			return getChildren(element).length > 0;
		}

		public Object[] getElements(Object inputElement) {
			ChannelTreeModel.TreeNode node = (ChannelTreeModel.TreeNode) inputElement;
			return treeModel.getChildren(node);
		}

		public void dispose() {
			
		}

		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			
		}
	}
	
	class TreeLabelProvider extends LabelProvider implements IFontProvider, IColorProvider {

		@Override
		public Image getImage(Object element) {
			ChannelTreeModel.TreeNode node = (ChannelTreeModel.TreeNode) element;
			return node.getImage();
		}

		@Override
		public String getText(Object element) {
			ChannelTreeModel.TreeNode node = (ChannelTreeModel.TreeNode) element;
			return node.getText();
		}

		public Font getFont(Object element) {
			ChannelTreeModel.TreeNode node = (ChannelTreeModel.TreeNode) element;
			return node.getFont();
		}

		public Color getBackground(Object element) {
			ChannelTreeModel.TreeNode node = (ChannelTreeModel.TreeNode) element;
			return node.getBackground();
		}

		public Color getForeground(Object element) {
			ChannelTreeModel.TreeNode node = (ChannelTreeModel.TreeNode) element;
			return node.getForeground();
		}
	
	}


}
